<!--  -->
<template>
  <div class="screen-wrapper" ref="canvasContainer" :style="{ 'background-color': `${page_info.bigpage_bg_color}`, 'background-image': `url(${page_info.bigpage_bg})` }">
    <div class="screen-content" ref="canvasContent" :style="canvasStyle">
      <component
        v-for="(item, index) in componentList"
        :key="index"
        :is="item.component_key"
        :id="item.id"
        :page_id="page_id"
        :component_key="item.component_key"
        :component_title="item.component_title"
        :datas="item.remote_data"
        :index="index"
        :ref="item.component_key"
        :w="item.w"
        :h="item.h"
        :x="item.x"
        :y="item.y"
      ></component>
    </div>
  </div>
</template>

<script>
import _ from "lodash";
export default {
  data() {
    return {
      ockReconnect: false, //是否真正建立连接
      timeout: 2500, //todo 2.5秒一次心跳
      timeoutObj: null, //心跳心跳倒计时
      serverTimeoutObj: null, //心跳倒计时
      timeoutnum: null, //断开 重连倒计时
      isClosed: false, //是否关闭ws
      lockReconnect: false, //锁定重连状态
      maxReconnectNum: 15, //最大重连次数
      currentReconnectNum: 0, //当前重连次数

      baseWidth: 1920,
      baseHeight: 1080,
      scale: 1,
      recommendedResolution: 3,
      containerSize: { width: 0, height: 0 },

      page_id: "",
      page_info: {},
      componentList: [],
      componentOptions: {
        2: 'U_bigScreen_storeRanking',
        3: 'U_bigScreen_SalesLeaderboard',
        4: 'U_bigScreen_pointRanking',
        5: 'U_bigScreen_activityApply',
        6: 'U_bigScreen_micro',
        7: 'U_bigScreen_exchangeLog',
        8: 'U_bigScreen_regLog',
        9: 'U_bigScreen_NoticeBar'
      },
    };
  },

  components: {
    U_bigScreen_storeRanking: () => import("./components/U_bigScreen_storeRanking.vue"),
    U_bigScreen_SalesLeaderboard: () => import("./components/U_bigScreen_SalesLeaderboard"),
    U_bigScreen_pointRanking: () => import("./components/U_bigScreen_pointRanking"),
    U_bigScreen_activityApply: () => import("./components/U_bigScreen_activityApply"),
    U_bigScreen_micro: () => import("./components/U_bigScreen_micro"),
    U_bigScreen_exchangeLog: () => import("./components/U_bigScreen_exchangeLog"),
    U_bigScreen_regLog: () => import("./components/U_bigScreen_regLog"),
    U_Texts: () => import("./components/U_Texts"),
    U_bigScreen_NoticeBar: () => import("./components/U_bigScreen_NoticeBar")
  },

  computed: {
    canvasStyle() {
      this.handleResolutionChange(this.recommendedResolution);
      this.calcScale();
      const offsetX = this.containerSize.width / 2 - (this.baseWidth * this.scale) / 2;
      const offsetY = this.containerSize.height / 2 - (this.baseHeight * this.scale) / 2;
      return {
        width: `${this.baseWidth}px`,
        height: `${this.baseHeight}px`,
        transform: `translate(${offsetX}px, ${offsetY}px) scale(${this.scale})`,
        transformOrigin: "0 0", // 确保从左上角开始缩放
      };
    }
  },
  activated() {},
  created() {
    this.page_id = this.$route.query.page_id;
    this.getData();
  },
  mounted() {
    this.initResizeObserver();
  },
  beforeDestroy() {
    this.resizeObserver && this.resizeObserver.disconnect();
    this.isClosed = true;
    this.websock && this.websock.close();
  },
  methods: {
    async getData() {
      let { result, msg, data } = await $http.post(
        "plugin.platform-screen.frontend.controllers.screen.index.get-module-data",
        {
          module_type: 1,
          search: { page_id: this.page_id }
        },
        "."
      );
      if (result == 0) return this.$toast(msg);
      this.page_info = JSON.parse(data.data.page_info);
      this.componentList = JSON.parse(data.data.datas);
      this.recommendedResolution = this.page_info.recommendedResolution;
      this.handleResolutionChange();
      this.initWebSocket();
    },
    // 监听容器尺寸变化
    initResizeObserver() {
      this.resizeObserver = new ResizeObserver(entries => {
        const { width, height } = entries[0].contentRect;
        this.containerSize = { width, height };
        this.calcScale();
      });
      this.resizeObserver.observe(this.$refs.canvasContainer);
    },
    handleResolutionChange() {
      const ResolutionOptions = {
        1: { width: 1024, height: 720 },
        2: { width: 1280, height: 720 },
        3: { width: 1920, height: 1080 },
        4: { width: 2560, height: 1440 },
        5: { width: 3840, height: 2160 },
        6: { width: 5120, height: 2880 },
        7: { width: 7680, height: 4320 }
      };
      const newRes = ResolutionOptions[this.recommendedResolution];
      this.baseWidth = newRes.width;
      this.baseHeight = newRes.height;
      this.calcScale();
    },
    // 计算缩放比例
    calcScale: _.throttle(function() {
      // 使用防抖优化
      const container = this.$refs.canvasContainer;
      if (!container) return;

      const cw = container.clientWidth;
      const ch = container.clientHeight;

      if (cw <= 0 || ch <= 0) return;

      const scaleX = Number((cw / this.baseWidth).toFixed(3));
      const scaleY = Number((ch / this.baseHeight).toFixed(3));
      this.scale = Math.min(scaleX, scaleY);
      this.scale = Math.max(Math.min(this.scale, 3), 0.1); // 限制缩放范围
    }, 250),
    initWebSocket() {
      console.log("initWebSocket 创建连接");
      this.currentReconnectNum += 1;
      this.websock = new WebSocket(`wss://${document.location.hostname}//ws`);
      // this.websock = new WebSocket("wss://dev15.yunzmall.com//ws");
      this.websock.onmessage = this.websocketonmessage;
      this.websock.onopen = this.websocketonopen;
      this.websock.onerror = this.websocketonerror;
      this.websock.onclose = this.websocketclose;
    },
    //连接建立之后执行send方法发送数据
    websocketonopen() {
      console.log("连接建立之后执行send方法发送数据");
      this.heartBeatStart();
    },
    //连接建立失败重连
    websocketonerror(e) {
      console.log("连接建立失败重连", e.type);
    },
    //关闭
    websocketclose(e) {
      this.$toast('websocket断开连接');
      console.log("断开连接", this.isClosed);
      this.clearHeartBeat();
      if (!this.isClosed) {
        this.reconnect();
      }
    },
    clearHeartBeat() {
      clearInterval(this.heartBeatInterval);
      this.heartBeatInterval = null;
    },
    // 数据接收
    websocketonmessage(e) {
      // console.log("后端接收过来的信息",e);
      if (e.data != "pong") {
        console.log("JSON: 后端接收过来的信息", JSON.parse(e.data));
        let data = JSON.parse(e.data);
        if (data.result) {
          return;
        }
        if (data.type == 1 && data.data.id == this.page_id) {
          // 装修后台有改动，更新页面数据
          this.page_info = JSON.parse(data.data.page_info);
          this.componentList = JSON.parse(data.data.datas);
          this.$forceUpdate();
        } else {
          // 更新组件数据
          // console.log("更新组件数据", data);
          this.componentList.forEach((item, index) => {
            let component = this.componentOptions[data.type]; // 根据id匹配对应的组件类型
            if (item.component_key == component) {
              try {
                this.$refs[component][0].setData(data.data);
              } catch (error) {
                console.log("error", error);
              }
              // this.$set(this.componentList, index, data.data);
            }
          });
        }
      }
    },
    heartBeatStart() {
      this.timeoutObj && clearTimeout(this.timeoutObj);
      this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
      this.timeoutObj = setTimeout(() => {
        //这里发送一个心跳，后端收到后，返回一个心跳消息，
        if (this.websock.readyState == 1) {
          this.websock.send(
            JSON.stringify({
              type: "register",
              data: { group: "platform-screen-update", i: this.fun.getKeyByI() }
            })
          );
          this.keepHeartBeat();
          this.currentReconnectNum = 0; //连接成功归零
        } else {
          //否则重连
          this.reconnect();
        }
      }, this.timeout);
    },
    keepHeartBeat() {
      this.heartBeatInterval = setInterval(() => {
        // 每隔2.8秒发送一个心跳包消息
        this.websock.send(JSON.stringify({ type: "`ping`" }));
      }, 2800);
    },
    reconnect() {
      //重新连接
      console.log("重新连接次数：", this.currentReconnectNum);
      if (this.lockReconnect || this.isClosed || this.currentReconnectNum >= this.maxReconnectNum) {
        if (this.websock) {
          this.websock.close();
        }
        return;
      }
      this.lockReconnect = true;
      //没连接上会一直重连，设置延迟避免请求过多
      this.timeoutnum && clearTimeout(this.timeoutnum);
      this.timeoutnum = setTimeout(() => {
        //新连接
        this.initWebSocket();
        this.lockReconnect = false;
      }, 3000);
    }
  }
};
</script>
<style lang="scss" rel="stylesheet/scss" scoped>
.screen-wrapper {
  width: 100vw;
  height: 100vh;
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  transform-origin: 0 0; /* 缩放起点在左上角 */
  position: absolute;
  overflow: hidden;
}
.screen-content {
  position: relative; /* 子组件使用绝对定位时参考此容器 */
}
</style>
